<?php
// +----------------------------------------------------------------------
// | sfadmin - Suifeng Administration
// +----------------------------------------------------------------------
// | Copyright (c) 2017-2020 http://suifeng.tech All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: suifeng <1787585212@qq.com>
// +----------------------------------------------------------------------

namespace app\admin\model;

use suifeng\Model;

class Module extends Model
{
    /**
     * 数据库表名。
     *
     * @var string
     */
    protected $name = 'admin_module';


    /**
     * 获取缓存的模块列表。
     *
     * @return array
     */
    public function get_cached_list()
    {
        $list = cache('model_admin_module::get_cached_list');

        if (!$list || APP_DEBUG) {
            $where['status'] = array('eq', 1);
            $order = 'sort asc, id asc';

            $rows = model('admin/module')->where($where)
            ->order($order)
            ->select();

            $list = array();
            foreach ($rows as $row) {
                $row['config'] = $row['config'] ? helper('admin/json')->decode($row['config']) : [];
                $list[$row['name']] = $row->getData();
            }

            cache('model_admin_module::get_cached_list', $list);
        }

        return $list;
    }

    /**
     * 获取缓存的模块信息。
     *
     * @param unknown $key
     * @return unknown|NULL
     */
    public function get_cached_module($key)
    {
        foreach ($this->get_cached_list() as $module_info) {
            if ($module_info['id'] == $key || $module_info['name'] == $key) {
                return $module_info;
            }
        }
        return null;
    }

    /**
     * 清除缓存。
     */
    public function clear_cache()
    {
        cache('model_admin_module::get_cached_list', null);
        cache('model_admin_module::get_admin_permissions', null);
    }

    /**
     * 检查是否是有效的模块？
     *
     * @param unknown $name
     * @return string
     */
    public function is_valid_module($name)
    {
        return realpath(APP_PATH . $name . '/module.php');
    }

    /**
     * 根据模块名，返回对应的模块实例。
     *
     * @param unknown $name
     */
    public function get_module_instance($name)
    {
        static $instances = null;

        if (isset($instances[$name])) {
            return $instances[$name];
        }

        $file = realpath(APP_PATH . $name . '/module.php');
        if ($file) {
            require_once $file;
            $class = '\\' . \think\App::$namespace . '\\' . $name . '\\Module';
            $instances[$name] = new $class();
        } else {
            $instances[$name] = null;
        }

        return $instances[$name];
    }

    /**
     * 调用指定模块的方法。
     *
     * @param unknown $module
     * @param unknown $method
     * @param unknown $args
     */
    public function invoke_module_method($module, $method, &$args = null)
    {
        $result = null;

        if (is_string($module)) {
            $module = $this->get_module_instance($module);
        }

        if ($module === null || !method_exists($module, $method)) {
            return null;
        }

        return $module->$method($args);
    }

    /**
     * 调用所有模块对应的方法。
     *
     * @param unknown $method
     * @param unknown $args
     */
    public function invoke_all_modules($method, &$args = null)
    {
        $result = null;

        foreach (array_keys($this->get_cached_list()) as $module_name) {
            $module_instance = $this->get_module_instance($module_name);
            if ($module_instance === null || !method_exists($module_instance, $method)) {
                continue;
            }

            $return = $module_instance->$method($args);

            if ($return !== null) {
                $result[] = $return;
            }
        }

        return $result;
    }

    public function get_installed_modules()
    {
        return array_keys($this->get_cached_list());
    }

    public function get_admin_permissions()
    {
        $list = cache('model_admin_module::get_admin_permissions');

        if (!$list || APP_DEBUG) {
            $list = array();

            foreach ($this->get_installed_modules() as $module_name) {
                $module_permissons = $this->invoke_module_method($module_name, 'admin_permissions');
                if ($module_permissons) {
                    $list = array_merge($list, $module_permissons);
                }
            }

            cache('model_admin_module::get_admin_permissions', $list);
        }

        return $list;
    }











    /**
     * 插入对象。
     *
     * @param unknown $data
     * @return unknown
     */
    public function insert_object($data)
    {
        return $this->save($data);
    }

    /**
     * 删除对象。
     *
     * @param unknown $id
     * @param unknown $data
     * @return \app\shop\model\Category
     */
    public function update_object($id, $data)
    {
        return $this->where('id', $id)->save($data);
    }

    /**
     * 删除对象。
     *
     * @param unknown $id
     * @return unknown
     */
    public function delete_object($id)
    {
        return $this->where('id', $id)->delete();
    }



//     /**
//      * 模型标题
//      */
//     protected $model_title  = '模块';

//     /**
//      * 模型字段
//      */
//     protected $model_fields = [
//         'id'            =>  [
//             'dbtype'        =>  'integer',
//             'title'         =>  'ID',
//             'identity'      =>  true,
//         ],
//         'name'          =>  [
//             'dbtype'        =>  'string',
//             'title'         =>  '名称',
//             'required'      =>  true,
//             'listable'      =>  true,
//             'editable'      =>  true,
//             'searchable'    =>  true,
//         ],
//         'title'         =>  [
//             'dbtype'        =>  'string',
//             'title'         =>  '标题',
//             'required'      =>  true,
//             'listable'      =>  true,
//             'editable'      =>  true,
//             'searchable'    =>  true,
//         ],
//         'description'   =>  [
//             'dbtype'        =>  'string',
//             'title'         =>  '描述',
//             'required'      =>  true,
//             'listable'      =>  true,
//             'editable'      =>  true,
//             'searchable'    =>  true,
//         ],
//         'developer'     =>  [
//             'dbtype'        =>  'string',
//             'title'         =>  '开发者',
//             'required'      =>  true,
//             'listable'      =>  true,
//             'editable'      =>  true,
//             'searchable'    =>  true,
//         ],
//         'version'       =>  [
//             'dbtype'        =>  'string',
//             'title'         =>  '版本',
//             'required'      =>  true,
//             'listable'      =>  true,
//             'editable'      =>  true,
//             'searchable'    =>  true,
//         ],
//         'create_time'   =>  [
//             'dbtype'        =>  'datetime',
//             'title'         =>  '创建时间',
//         ],
//         'update_time'   =>  [
//             'dbtype'        =>  'datetime',
//             'title'         =>  '更新时间',
//         ],
//         'sort'          =>  [
//             'dbtype'        =>  'integer',
//             'title'         =>  '排序',
//             'control'       =>  'number',
//             'listable'      =>  true,
//             'editable'      =>  true,
//         ],
//         'status'        =>  [
//             'dbtype'        =>  'integer',
//             'title'         =>  '状态',
//             'default'       =>  1,
//             'control'       =>  'toggle',
//             'column'        =>  'status',
//             'listable'      =>  true,
//             'editable'      =>  true,
//         ],
//     ];

//     /**
//      * 获取模块列表，支持缓存。
//      *
//      * @return array
//      */
//     public function get_all_modules()
//     {
//         $list = cache('model_admin_module::get_module_list');
//         if (!$list || APP_DEBUG) {
//             $where['status'] = array('eq', 1);
//             $order = 'sort asc, id asc';

//             $rows = $this->where($where)
//                 ->order($order)
//                 ->select();

//             $list = array();
//             foreach ($rows as $row) {
//                 $row['config'] = $row['config'] ? json_decode($row['config']) : [];
//                 $row['admin_menu'] = $row['admin_menu'] ? json_decode($row['admin_menu']) : [];
//                 $row['user_nav'] = $row['user_nav'] ? json_decode($row['user_nav']) : [];
//                 $list[$row['name']] = $row->getData();
//             }

//             cache('model_admin_module::get_module_list', $list);
//         }
//         return $list;
//     }

//     /**
//      * 清除缓存。
//      */
//     public function clear_cache()
//     {
//         cache('model_admin_module::get_module_list', null);
//     }


















// //     /**
// //      * 自动验证规则
// //      * @author jry <598821125@qq.com>
// //      */
// //     protected $_validate = array(
// //         array('name', 'require', '模块名称不能为空', self::MUST_VALIDATE, 'regex', self::MODEL_BOTH),
// //         array('name', '', '该模块已存在', self::MUST_VALIDATE, 'unique', self::MODEL_BOTH),
// //         array('title', 'require', '模块标题不能为空', self::MUST_VALIDATE, 'regex', self::MODEL_BOTH),
// //         array('description', 'require', '模块描述不能为空', self::MUST_VALIDATE, 'regex', self::MODEL_BOTH),
// //         array('developer', 'require', '模块开发者不能为空', self::MUST_VALIDATE, 'regex', self::MODEL_BOTH),
// //         array('version', 'require', '模块版本不能为空', self::MUST_VALIDATE, 'regex', self::MODEL_BOTH),
// //         array('admin_menu', 'require', '模块菜单节点不能为空', self::MUST_VALIDATE, 'regex', self::MODEL_BOTH),
// //     );

// //     /**
// //      * 自动完成规则
// //      * @author jry <598821125@qq.com>
// //      */
// //     protected $_auto = array(
// //         array('create_time', 'time', self::MODEL_INSERT, 'function'),
// //         array('update_time', 'time', self::MODEL_BOTH, 'function'),
// //         array('sort', '0', self::MODEL_INSERT),
// //         array('status', '1', self::MODEL_INSERT),
// //     );

//     /**
//      * 安装描述文件名
//      * @author jry <598821125@qq.com>
//      */
//     public function install_file()
//     {
//         return 'opencmf.php';
//     }

//     /**
//      * 获取模块菜单
//      * @author jry <598821125@qq.com>
//      */
//     public function getAdminMenu($module_name = '')
//     {
//         if ('' == $module_name) {
//             $module_name = request()->module();
//         }

//         // 获取模块左侧导航
//         $where['name']   = $module_name;
//         $module_info     = $this->where($where)->find();
//         $_side_menu_list = json_decode($module_info['admin_menu'], true);

//         // 转换成树结构
//         $tree = new tree();
//         return $tree->list2tree($_side_menu_list);
//     }

//     /**
//      * 获取模块当前菜单
//      * @author jry <598821125@qq.com>
//      */
//     public function getCurrentMenu($module_name = '')
//     {
//         if ('' == $module_name) {
//             $module_name = request()->module();
//         }
//         $admin_menu = $this->getFieldByName(ucfirst($module_name), 'admin_menu');
//         $admin_menu = json_decode($admin_menu, true);
//         foreach ($admin_menu as $key => $val) {
//             if (isset($val['url'])) {
//                 $config_url  = url(lcfirst($val['url']));
//                 $current_url = url(request()->module() . '/' . request()->controller() . '/' . request()->action());
//                 if ($config_url === $current_url) {
//                     $result = $val;
//                     return $result;
//                 }
//             }
//         }
//     }

//     /**
//      * 获取所有模块菜单
//      * @param string $addon_dir
//      * @author jry <598821125@qq.com>
//      */
//     public function getAllMenu()
//     {
//         $uid        = is_login();
//         $user_group = model('Admin/Access')->getFieldByUid($uid, 'group'); // 获得当前登录用户信息
//         $group_info = model('Admin/Group')->find($user_group);
//         $group_auth = json_decode($group_info['menu_auth'], true); // 获得当前登录用户所属部门的权限列表

//         // 获取所有菜单
//         $menu_list = cache('MENU_LIST_' . $uid);
//         if (!$menu_list || APP_DEBUG === true) {
//             $con['status']      = 1;
//             $system_module_list = $this->where($con)->order('sort asc, id asc')->select();
//             $tree               = new \suifeng\Tree();
//             $menu_list          = array();
//             foreach ($system_module_list as $key => &$module) {
//                 $menu = json_decode($module['admin_menu'], true);

//                 // 判断当前用户组的权限是否包含当前模块
//                 if (isset($group_auth[$module['name']]) || $user_group == 1) {
//                     if ($user_group <> 1) {
//                         $menu_tmp     = array();
//                         $menu_tmp_tmp = array();
//                         foreach ($menu as $key1 => &$val1) {
//                             if (in_array($val1['id'], $group_auth[$module['name']]) && $val1['pid'] !== '0') {
//                                 $menu_tmp[$val1['id']] = $menu[$key1];
//                             }
//                         }
//                         if (count($menu_tmp) > 0) {
//                             foreach ($menu_tmp as $key2 => &$val2) {
//                                 $_pid = $val2['pid'];
//                                 do {
//                                     if (!isset($menu_tmp[$menu[$_pid]['id']])) {
//                                         $menu_tmp_tmp[$menu[$_pid]['id']] = $menu[$_pid];
//                                     }
//                                     $_pid = $menu[$_pid]['pid'];
//                                 } while ($_pid > 0);
//                             }
//                             $menu = array_merge($menu_tmp, $menu_tmp_tmp);
//                         }
//                     }

//                     $temp = $tree->list2tree($menu);
//                     if (isset($temp[0])) {
//                         $menu_list[$module['name']]         = $temp[0];
//                         $menu_list[$module['name']]['id']   = $module['id'];
//                         $menu_list[$module['name']]['name'] = $module['name'];
//                     }
//                 }
//             }

//             // 如果模块顶级菜单配置了top字段则移动菜单至top所指的模块下边
//             foreach ($menu_list as $key => &$value) {
//                 if (isset($value['top'])) {
//                     if ($menu_list[$value['top']]) {
//                         $menu_list[$value['top']]['_child'] = array_merge(
//                             $menu_list[$value['top']]['_child'],
//                             $value['_child']
//                         );
//                         unset($menu_list[$key]);
//                     }
//                 }
//             }

//             cache('MENU_LIST_' . $uid, $menu_list, 3600); // 缓存配置
//         }
//         return $menu_list;
//     }

//     /**
//      * 根据菜单ID的获取其所有父级菜单
//      * @param array $current_menu 当前菜单信息
//      * @return array 父级菜单集合
//      * @author jry <598821125@qq.com>
//      */
//     public function getParentMenu($current_menu = '', $module_name = '')
//     {
//         if ('' == $module_name) {
//             $module_name = request()->module();
//         }
//         if (!$current_menu) {
//             $current_menu = $this->getCurrentMenu();
//         }
//         if (!$current_menu) {
//             return false;
//         }
//         $admin_menu = $this->getFieldByName(ucfirst($module_name), 'admin_menu');
//         $admin_menu = json_decode($admin_menu, true);
//         $pid        = $current_menu['pid'];
//         $temp       = array();
//         $result[]   = $current_menu;
//         while (true) {
//             foreach ($admin_menu as $key => $val) {
//                 if ($val['id'] == $pid) {
//                     $pid = $val['pid'];
//                     array_unshift($result, $val); // 将父菜单插入到第一个元素前
//                 }
//             }
//             if ($pid == '0') {
//                 break;
//             }
//         }
//         return $result;
//     }

//     /**
//      * 获取模块列表
//      * @param string $addon_dir
//      * @author jry <598821125@qq.com>
//      */
//     public function getAll()
//     {
//         // 获取除了Common等系统模块外的用户模块
//         // 文件夹下必须有$install_file定义的安装描述文件
//         $dirs = array_map('basename', glob(APP_DIR . '*', GLOB_ONLYDIR));
//         foreach ($dirs as $dir) {
//             $config_file = APP_PATH . $dir . '/' . $this->install_file();
//             if (is_file($config_file)) {
//                 $module_dir_list[]                      = $dir;
//                 $temp_arr                               = include $config_file;
//                 $temp_arr['info']['status']             = -1; //未安装
//                 $module_list[$temp_arr['info']['name']] = $temp_arr['info'];
//             }
//         }

//         // 获取系统已经安装的模块信息
//         $installed_module_list = $this->field(true)
//             ->order('sort asc,id asc')
//             ->select();
//         if ($installed_module_list) {
//             foreach ($installed_module_list as &$module) {
//                 $new_module_list[$module['name']]               = $module;
//                 $new_module_list[$module['name']]['admin_menu'] = json_decode($module['admin_menu'], true);
//             }
//             // 系统已经安装的模块信息与文件夹下模块信息合并
//             $module_list = array_merge($module_list, $new_module_list);
//         }

//         foreach ($module_list as &$val) {
//             switch ($val['status']) {
//                 case '-2': // 损坏
//                     $val['status_icon']                          = '<span class="text-danger">删除记录</span>';
//                     $val['right_button']['damaged']['title']     = '删除记录';
//                     $val['right_button']['damaged']['attribute'] = 'class="label label-danger-outline label-pill ajax-get" href="' . U('setStatus', array('status' => 'delete', 'ids' => $val['id'])) . '"';
//                     break;
//                 case '-1': // 未安装
//                     $val['status_icon']                                 = '<i class="fa fa-download text-success"></i>';
//                     $val['right_button']['install_before']['title']     = '安装';
//                     $val['right_button']['install_before']['attribute'] = 'class="label label-success-outline label-pill" href="' . U('install_before', array('name' => $val['name'])) . '"';
//                     break;
//                 case '0': // 禁用
//                     $val['status_icon']                                   = '<i class="fa fa-ban text-danger"></i>';
//                     $val['right_button']['update_info']['title']          = '更新菜单';
//                     $val['right_button']['update_info']['attribute']      = 'class="label label-info-outline label-pill ajax-get no-refresh" href="' . U('updateInfo', array('id' => $val['id'])) . '"';
//                     $val['right_button']['forbid']['title']               = '启用';
//                     $val['right_button']['forbid']['attribute']           = 'class="label label-success-outline label-pill ajax-get" href="' . U('setStatus', array('status' => 'resume', 'ids' => $val['id'])) . '"';
//                     $val['right_button']['uninstall_before']['title']     = '卸载';
//                     $val['right_button']['uninstall_before']['attribute'] = 'class="label label-danger-outline label-pill " href="' . U('uninstall_before', array('id' => $val['id'])) . '"';
//                     break;
//                 case '1': // 正常
//                     $val['status_icon']                              = '<i class="fa fa-check text-success"></i>';
//                     $val['right_button']['update_info']['title']     = '更新菜单';
//                     $val['right_button']['update_info']['attribute'] = 'class="label label-info-outline label-pill ajax-get no-refresh" href="' . U('updateInfo', array('id' => $val['id'])) . '"';
//                     if (!$val['is_system']) {
//                         $val['right_button']['forbid']['title']               = '禁用';
//                         $val['right_button']['forbid']['attribute']           = 'class="label label-warning-outline label-pill ajax-get" href="' . U('setStatus', array('status' => 'forbid', 'ids' => $val['id'])) . '"';
//                         $val['right_button']['uninstall_before']['title']     = '卸载';
//                         $val['right_button']['uninstall_before']['attribute'] = 'class="label label-danger-outline label-pill " href="' . U('uninstall_before', array('id' => $val['id'])) . '"';
//                     }
//                     break;
//             }
//         }
//         return $module_list;
//     }

//     /**
//      * 获取模块名称列表
//      * @param string $addon_dir
//      * @author jry <598821125@qq.com>
//      */
//     public function getNameList()
//     {
//         $list = $this->getField('name', true);
//         foreach ($list as $val) {
//             $return[$val] = $val;
//         }
//         return $return;
//     }

//     /**
//      * 获取模块列表。
//      *
//      * @return array
//      */
//     public function lists()
//     {
//         $map['status'] = array('eq', 1);
//         $rows = $this->where($map)->order('sort asc, id asc')->select();
//         foreach ($rows as $row) {
//             $row['config'] = $row['config'] ? json_decode($row['config'], true) : [];
//             $row['admin_menu'] = $row['admin_menu'] ? json_decode($row['admin_menu'], true) : [];
//             $row['user_nav'] = $row['user_nav'] ? json_decode($row['user_nav'], true) : [];
//             $list[$row['name']] = $row->getData();
//         }
//         return $list;
//     }
}
